home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / smaltalk.lha / smalltalk-1.1.1 / stix / Rectangle.st < prev    next >
Text File  |  1991-09-13  |  12KB  |  376 lines

  1. "========================================================================
  2. |   Rectangle Class
  3.  ========================================================================"
  4.  
  5. "======================================================================
  6. |
  7. | Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  8. | Written by Steve Byrne.
  9. |
  10. | This file is part of GNU Smalltalk.
  11. |
  12. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  13. | under the terms of the GNU General Public License as published by the Free
  14. | Software Foundation; either version 1, or (at your option) any later version.
  15. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  16. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  17. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  18. | details.
  19. | You should have received a copy of the GNU General Public License along with
  20. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  21. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  22. |
  23.  ======================================================================"
  24.  
  25.  
  26. "
  27. |     Change Log
  28. | ============================================================================
  29. | Author       Date       Change
  30. | sbb         13 Sep 91      Added #= and #hash methods.
  31. |
  32. | dougm      19 Apr 90    Initial definitions for Rectangle class (needs Point)
  33. |
  34. "
  35.  
  36. Object subclass: #Rectangle
  37.        instanceVariableNames: 'origin corner'
  38.        classVariableNames: ''
  39.        poolDictionaries: ''
  40.        category: nil !
  41.  
  42. Rectangle comment:
  43. 'Beginning of the Rectangle class for simple display manipulation.
  44.  Rectangles require the Point class to be available.  An extension
  45.  to the Point class is made here that since it requires Rectangles
  46.  to be defined (see converting)' !
  47.  
  48. !Rectangle class methodsFor: 'instance creation'!
  49.  
  50. origin: originPoint corner: cornerPoint
  51.     ^self new origin: originPoint corner: cornerPoint
  52. !
  53.  
  54. origin: originPoint extent: extentPoint
  55.     ^self new origin: originPoint corner: (originPoint + extentPoint)
  56. !
  57.  
  58. left: leftNumber right: rightNumber top: topNumber bottom: bottomNumber
  59.     ^self new origin: (Point x: leftNumber y: topNumber) corner: (Point x: rightNumber y: bottomNumber)
  60. !!
  61.  
  62. !Rectangle methodsFor: 'accessing'!
  63.  
  64. origin: originPoint corner: cornerPoint
  65.     origin _ originPoint.
  66.     corner _ cornerPoint
  67. !
  68.  
  69. origin
  70.     ^origin
  71. !
  72.  
  73. corner
  74.        ^corner
  75. !
  76.  
  77. topLeft
  78.     ^origin
  79. !
  80.  
  81. topCenter
  82.     ^Point x: (origin x + (self width / 2)) y: (origin y)
  83. !
  84.  
  85. topRight
  86.     ^Point x: (corner x) y: (origin y)
  87. !
  88.  
  89. rightCenter
  90.     ^Point x: (corner x) y: (origin y + (self height / 2))
  91. !
  92.  
  93. bottomCenter
  94.     ^Point x: (origin x + (self width / 2)) y: (corner y)
  95. !
  96.  
  97. bottomLeft
  98.     ^Point x: (origin x) y: (corner y)
  99. !
  100.  
  101. bottomRight
  102.     ^corner
  103. !
  104.  
  105. leftCenter
  106.     ^Point x: (origin x) y: (origin y + (self height / 2))
  107. !
  108.  
  109. center
  110.     ^Point x: (origin x + (self width / 2))
  111.        y: (origin y + (self height / 2))
  112. !
  113.  
  114. area
  115.     ^ (self width) * (self height)
  116. !
  117.  
  118. width
  119.     ^(corner x) - (origin x)
  120. !
  121.  
  122. height
  123.     ^(corner y) - (origin y)
  124. !
  125.  
  126. extent
  127.     ^Point x: (self width) y: (self height)
  128. !
  129.  
  130. top
  131.     ^(origin y)
  132. !
  133.  
  134. right
  135.     ^(corner x)
  136. !
  137.  
  138. bottom
  139.     ^(corner y)
  140. !
  141.  
  142. left
  143.     ^(origin x)
  144. !!
  145.  
  146.  
  147. "Not yet implemented: messages to set the locations as mentioned on p 346"
  148.  
  149.  
  150.  
  151. !Rectangle methodsFor: 'testing'!
  152.  
  153. containsPoint: aPoint
  154.     ^(origin < aPoint) & (corner > aPoint)
  155. !
  156.  
  157. contains: aRectangle
  158.     ^(self containsPoint: (aRectangle origin)) &
  159.        (self containsPoint: (aRectangle corner))
  160. !
  161.  
  162. intersects: aRectangle
  163.     ^(self containsPoint: aRectangle topLeft) or:
  164.        [(self containsPoint: aRectangle topRight) or:
  165.            [(self containsPoint: aRectangle bottomLeft) or:
  166.                [(self containsPoint: aRectangle bottomRight)]]]
  167. !
  168.  
  169. = aRectangle
  170.     ^(origin = aRectangle origin)
  171.     and: [ corner = aRectangle corner ]
  172. !
  173.  
  174. hash
  175.     ^(origin hash) * (corner hash)
  176. !!
  177.  
  178. !Rectangle methodsFor: 'rectangle functions'!
  179.  
  180. amountToTranslateWithin: aRectangle
  181.     ^(aRectangle origin)-origin
  182. !
  183.  
  184. "----------------------------------------------------------------
  185. |areasOutside: aRectangle
  186. | most complicated of the Rectangle primitives
  187. | The basic methodology is to first determine that there is an
  188. | intersection by finding the overlapping rectangle.  From the
  189. | overlapping rectangle, first determine if it runs along an edge.
  190. | If it doesn't, extend the rectangle up to the top edge and add
  191. | the new rectangle to the collection and start the rest of the
  192. | process.  If the left edge does not touch the left edge of self,
  193. | extend it to the edge saving the new rectangle.  Then do the
  194. | same to the right edge.  Then check top and bottom edges.  Most
  195. | of the time only 2 or 3 rectangles get formed, occasionally 4.
  196. | It should be possible to never get more than 3 but requires more
  197. | work.
  198.  ----------------------------------------------------------------"
  199.  
  200. areasOutside: aRectangle
  201.     | collect iRect tmp |
  202.     iRect _ self intersect: aRectangle.
  203.     (iRect = nil) ifTrue: [^nil]. "case of no intersection"
  204.                                "the collect collection gathers Rectangles"
  205.     collect _ OrderedCollection new: 4.
  206.                                "is it floating or on the edge?"
  207.     (((iRect top) ~= self top) &
  208.              ((iRect bottom) ~= self bottom) &
  209.                    ((iRect left) ~= self left) & ((iRect right) ~= self right))
  210.        ifTrue: "entirely in the center."
  211.            [tmp _ Rectangle origin: (Point x: iRect left y: self top)
  212.                             corner: iRect bottomRight.
  213.             collect add: tmp.
  214.             iRect _ iRect merge: tmp].
  215.     ((iRect left) ~= self left)
  216.        ifTrue:                 "doesn't touch left edge so make it touch"
  217.            [tmp _ Rectangle origin: (Point x: self left y: iRect top)
  218.                                 corner: iRect bottomLeft.
  219.                 collect add: tmp.
  220.                                "merge new (tmp) with overlap to keep track"
  221.                 iRect _ iRect merge: tmp].
  222.     ((iRect right) ~= self right)
  223.        ifTrue:                 "doesn't touch right edge so extendi it"
  224.            [tmp _ Rectangle origin: iRect topRight
  225.                                 corner: (Point x: self right y: iRect bottom).
  226.                 collect add: tmp.
  227.                 iRect _ iRect merge: tmp].
  228.     (((iRect left) ~= self left) | ((iRect top) ~= self top))
  229.        ifTrue:                 "whole top part can be taken now"
  230.            [tmp _ Rectangle origin: origin corner: iRect topRight.
  231.                 collect add: tmp].
  232.     (((iRect right) ~= self right) | ((iRect bottom) ~= self bottom))
  233.        ifTrue:                 "whole bottom open and can be taken"
  234.            [tmp _ Rectangle origin: iRect bottomLeft corner: corner.
  235.                 collect add: tmp].
  236.     ^collect
  237. !
  238.  
  239. expandBy: delta
  240.     delta _ delta asRectangle.    "not completed"
  241.     (delta isMemberOf: Point) ifTrue:
  242.        [^Rectangle origin: (origin-delta)
  243.                    corner: (corner+delta)].
  244.     (delta isMemberOf: Rectangle) ifTrue:
  245.        [^Rectangle origin: (origin-(delta origin))
  246.                    corner: (corner+(delta corner))].
  247.     (delta isKindOf: Number) ifTrue:
  248.        [^Rectangle left: (origin x)-delta
  249.                    right:(corner x)+delta
  250.                    top:  (origin y)-delta
  251.                    bottom:(corner y)+delta].
  252.     self error: 'Illegal delta value'
  253. !
  254.  
  255. insetBy: delta
  256.     (delta isMemberOf: Point) ifTrue:
  257.        [^Rectangle origin: (origin+delta)
  258.                    corner: (corner-delta)].
  259.     (delta isMemberOf: Rectangle) ifTrue:
  260.        [^Rectangle origin: (origin+(delta origin))
  261.                    corner: (corner-(delta corner))].
  262.     (delta isKindOf: Number) ifTrue:
  263.        [^Rectangle left: (origin x)+delta
  264.                    right:(corner x)-delta
  265.                    top:  (origin y)+delta
  266.                    bottom:(corner y)-delta].
  267.     self error: 'Illegal delta value'
  268. !
  269.  
  270. insetOriginBy: originDeltaPoint corner: cornerDeltaPoint
  271.     ^Rectangle origin: origin + originDeltaPoint
  272.               corner: corner + cornerDeltaPoint
  273. !
  274.  
  275. merge: aRectangle
  276.     | orig corn |
  277.     orig _ Point x: ((origin x) min: (aRectangle origin x))
  278.                 y: ((origin y) min: (aRectangle origin y)).
  279.     corn _ Point x: ((corner x) max: (aRectangle corner x))
  280.                 y: ((corner y) max: (aRectangle corner y)).
  281.     ^Rectangle origin: orig corner: corn
  282. !
  283.  
  284. "--------------------------------------------------------------
  285. | A intersect: B
  286. |   returns the rectangle (if any) created by the overlap of
  287. |   rectangles A and B.  There are 10 possible overlap situations:
  288. |      A inside B
  289. |      B inside A
  290. |      A overlaps B at one of the four corners (1 point inside)
  291. |      A overlaps B on one of the four sides (2 points inside)
  292.  ---------------------------------------------------------------"
  293.  
  294. intersect: aRectangle
  295.     (self contains: aRectangle) ifTrue: [^Rectangle origin: aRectangle origin
  296.                                                    corner: aRectangle corner].
  297.     (aRectangle contains: self)  ifTrue: [^Rectangle origin: origin
  298.                                                     corner: corner].
  299.     (self containsPoint: aRectangle topLeft)
  300.        ifTrue: [ (self containsPoint: aRectangle topRight)
  301.                      ifTrue: [^Rectangle origin: aRectangle origin
  302.                                          corner: (Point x: aRectangle corner x
  303.                                                        y: corner y)]
  304.                      ifFalse: [^Rectangle origin: aRectangle origin
  305.                                           corner: corner]].
  306.     (self containsPoint: aRectangle topRight)
  307.        ifTrue: [^Rectangle origin: (Point x: origin x y: aRectangle origin y)
  308.                            corner: (Point x: aRectangle corner x y: corner y)].
  309.     (self containsPoint: aRectangle bottomLeft)
  310.        ifTrue: [ (self containsPoint: aRectangle bottomRight)
  311.                      ifTrue: [^Rectangle origin: (Point x: aRectangle origin x
  312.                                                         y: origin y)
  313.                                          corner: aRectangle corner]
  314.                      ifFalse: [^Rectangle origin: (Point x: aRectangle origin x
  315.                                                          y: origin y)
  316.                                           corner: aRectangle corner]].
  317.     (self containsPoint: aRectangle bottomRight)
  318.        ifTrue: [^Rectangle origin: origin corner: aRectangle corner]
  319.        ifFalse: [^nil]
  320. !!
  321.  
  322. !Rectangle methodsFor: 'printing'!
  323.  
  324. printOn: aStream
  325.     origin printOn: aStream.
  326.     ' corner: ' printOn: aStream.
  327.     corner printOn: aStream
  328. !
  329.  
  330. storeOn: aStream
  331.     '(Rectangle origin: ' storeOn: aStream.
  332.     origin storeOn: aStream.
  333.     ' corner: ' storeOn: aStream.
  334.     corner storeOn: aStream.
  335.     ')' storeOn: aStream
  336. !!
  337.  
  338. !Rectangle methodsFor: 'truncation and round off'!
  339.  
  340. rounded
  341.     ^Rectangle origin: origin rounded corner: corner rounded
  342. !!
  343.  
  344. !Rectangle methodsFor: 'transforming'!
  345. moveBy: aPoint
  346.     origin _ origin + aPoint.
  347.     corner _ corner + aPoint
  348. !
  349.  
  350. moveTo: aPoint
  351.     | diff |
  352.     diff _ aPoint - origin.
  353.     origin _ aPoint.
  354.     corner _ corner + diff
  355. !
  356.  
  357. scaleBy: scale
  358.     ^Rectangle origin: origin * scale corner: corner * scale
  359. !
  360.  
  361. translateBy: factor
  362.     ^Rectangle origin: origin + factor corner: corner + factor
  363. !!
  364.  
  365. !Point methodsFor: 'converting'!
  366.  
  367. corner: aPoint
  368.     ^Rectangle origin: self corner: aPoint
  369. !
  370.  
  371. extent: aPoint
  372.     ^Rectangle origin: self extent: aPoint
  373. !!
  374.